package com.clear.honghefinance.biz.modules.account.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.clear.honghefinance.biz.modules.system.member.domain.vo.AdminDTO;
import com.clear.honghefinance.biz.modules.account.converter.AccountBookConverter;
import com.clear.honghefinance.biz.modules.account.domain.dto.*;
import com.clear.honghefinance.biz.modules.account.domain.entity.AccountBook;
import com.clear.honghefinance.biz.modules.account.domain.vo.GetAccountBookDetailVO;
import com.clear.honghefinance.biz.modules.account.domain.vo.ListAccountBookVO;
import com.clear.honghefinance.biz.modules.account.mapper.AccountBookMapper;
import com.clear.honghefinance.biz.modules.account.service.IAccountBookService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.clear.honghefinance.common.dto.entity.PageResult;
import com.clear.honghefinance.common.exception.BizException;
import com.clear.honghefinance.common.service.TokenService;
import com.clear.honghefinance.common.util.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;

/**
 * <p>
 * 账套 服务实现类
 * </p>
 *
 * @author 程序员clear
 * @since 2024-08-20
 */
@Service
@Slf4j
public class AccountBookServiceImpl extends ServiceImpl<AccountBookMapper, AccountBook> implements IAccountBookService {

    @Resource
    private TokenService<AdminDTO> tokenService;

    /**
     * 创建账套
     *
     * @param dto
     * @return
     */
    @Override
    public boolean add(AddAccountBookDTO dto) {
        if (log.isInfoEnabled()) {
            log.info("创建账套中，入参：{}", JSON.toJSONString(dto));
        }
        try {
            AccountBook accountBook = AccountBookConverter.INSTANCE.convertDTOToAccountBookEntity(dto);
            accountBook.setMemberId(tokenService.getThreadLocalUserId());
            accountBook.setTenantId(tokenService.getThreadLocalTenantId());
            accountBook.initDefault();

            if (!this.save(accountBook)) {
                return false;
            }
        } catch (Exception e) {
            log.error("创建账套异常 {}", e.getMessage(), e);
            throw new BizException("创建账套异常");
        }
        return false;
    }

    /**
     * 编辑账套
     *
     * @param dto
     * @return
     */
    @Override
    public boolean update(UpdateAccountBookDTO dto) {
        if (log.isInfoEnabled()) {
            log.info("编辑账套中，入参：{}", JSON.toJSONString(dto));
        }
        try {
            AccountBook accountBook = AccountBookConverter.INSTANCE.convertDTOToAccountBookEntity(dto);
            accountBook.setUpdateMemberId(tokenService.getThreadLocalUserId());
            accountBook.setUpdateTime(DateUtil.getSystemTime());

            LambdaUpdateWrapper<AccountBook> lambdaUpdateWrapper = Wrappers.<AccountBook>lambdaUpdate()
                    .eq(AccountBook::getId, dto.getId())
                    .eq(AccountBook::getTenantId, tokenService.getThreadLocalTenantId());

            if (!this.update(accountBook, lambdaUpdateWrapper)) {
                return false;
            }
        } catch (Exception e) {
            log.error("编辑账套异常 {}", e.getMessage(), e);
            throw new BizException("编辑账套异常");
        }
        return false;
    }


    /**
     * 禁用启用账套
     *
     * @param dto
     * @return
     */
    @Override
    public boolean updateDisable(UpdateAccountBookStateDTO dto) {
        if (log.isInfoEnabled()) {
            log.info("{}账套中，入参：{}", dto.getDisable() ? "禁用" : "启用", JSON.toJSONString(dto));
        }
        try {
            LambdaUpdateWrapper<AccountBook> lambdaUpdateWrapper = Wrappers.<AccountBook>lambdaUpdate()
                    .eq(AccountBook::getId, dto.getId())
                    .eq(AccountBook::getDisable, !dto.getDisable())  // 状态与传入的不同才会改变
                    // 只改变未删除的账套的禁用状态
                    .eq(AccountBook::getDelFlag, false)
                    .set(AccountBook::getDisable, dto.getDisable())
                    .set(AccountBook::getUpdateMemberId, tokenService.getThreadLocalUserId())
                    .set(AccountBook::getUpdateTime, DateUtil.getSystemTime());

            if (this.update(lambdaUpdateWrapper)) {
                return true;
            } else {
                throw new BizException(String.format("%s账套异常", dto.getDisable() ? "禁用" : "启用"));
            }
        } catch (Exception e) {
            log.error("{}账套异常 {}", dto.getDisable() ? "禁用" : "启用", e.getMessage(), e);
            throw new BizException(String.format("%s账套异常", dto.getDisable() ? "禁用" : "启用"));
        }
    }

    /**
     * 删除账套
     *
     * @param dto
     * @return
     */
    @Override
    public boolean delete(DeleteAccountBookDTO dto) {
        if (log.isInfoEnabled()) {
            log.info("删除账套中，入参：{}", JSON.toJSONString(dto));
        }
        try {
            LambdaUpdateWrapper<AccountBook> lambdaUpdateWrapper = Wrappers.<AccountBook>lambdaUpdate()
                    .eq(AccountBook::getId, dto.getId())
                    .eq(AccountBook::getDelFlag, true)
                    // 目前只能删除自己的账套
                    .eq(AccountBook::getTenantId, tokenService.getThreadLocalTenantId())
                    .set(AccountBook::getDelFlag, false)
                    .set(AccountBook::getUpdateMemberId, tokenService.getThreadLocalUserId())
                    .set(AccountBook::getUpdateTime, DateUtil.getSystemTime());

            if (this.update(lambdaUpdateWrapper)) {
                return true;
            } else {
                if (log.isInfoEnabled()) {
                    log.info("删除账套异常，入参：{}", JSON.toJSONString(dto));
                }
                throw new BizException("删除账套异常");
            }
        } catch (Exception e) {
            log.error("删除账套异常 {}", e.getMessage(), e);
            throw new BizException("删除账套异常");
        }
    }

    /**
     * 查询账套列表
     *
     * @param dto
     * @return
     */
    @Override
    public PageResult<ListAccountBookVO> list(ListAccountBookDTO dto) {
        if (log.isInfoEnabled()) {
            log.info("查看账套列表中，入参：{}", JSON.toJSONString(dto));
        }
        try {
            IPage<AccountBook> page = new Page<>();
            page.setCurrent(dto.getPageNum());
            page.setSize(dto.getPageSize());

            // select * from account_book company_name like %companyName% and disable = disable and del_flag = false
            LambdaUpdateWrapper<AccountBook> lambdaUpdateWrapper = Wrappers.<AccountBook>lambdaUpdate()
                    .eq(AccountBook::getDelFlag, false)
                    .eq(Objects.nonNull(dto.getDisable()), AccountBook::getDisable, dto.getDisable())
                    .like(StringUtils.isNotBlank(dto.getCompanyName()), AccountBook::getCompanyName, dto.getCompanyName())
                    // 只能查到当前租户的账套
                    .eq(AccountBook::getTenantId, tokenService.getThreadLocalTenantId())
                    // 根据更新时间倒序
                    .orderByDesc(AccountBook::getUpdateTime);

            this.page(page, lambdaUpdateWrapper);
            List<AccountBook> records = page.getRecords();

            PageResult<ListAccountBookVO> pageResult = new PageResult<>();
            if (CollectionUtils.isNotEmpty(records)) {
                List<ListAccountBookVO> list = AccountBookConverter.INSTANCE
                        .convertAccountBookEntityToListAccountBookVO(records);
                pageResult.setList(list);
                pageResult.setPageNum(dto.getPageNum());
                pageResult.setPageSize(dto.getPageSize());
                pageResult.setTotal((int) page.getTotal());
                pageResult.setPages((int) page.getPages());
            }
            return pageResult;
        } catch (Exception e) {
            log.error("查询账套异常 {}", e.getMessage(), e);
            throw new BizException("查询账套异常");
        }
    }

    /**
     * 查看账套明细
     *
     * @param id 账套id
     */
    @Override
    public GetAccountBookDetailVO getDetailById(long id) {
        log.info("查看账套明细中，入参：{}", id);
        try {
            LambdaQueryWrapper<AccountBook> lambdaQueryWrapper = Wrappers.<AccountBook>lambdaQuery()
                    .eq(AccountBook::getId, id)
                    .eq(AccountBook::getDelFlag, false)
                    // 只能查到当前租户的账套
                    .eq(AccountBook::getTenantId, tokenService.getThreadLocalTenantId());
            AccountBook accountBook = this.getOne(lambdaQueryWrapper);
            if (Objects.isNull(accountBook)) {
                throw new BizException("账套不存在");
            }
            return AccountBookConverter.INSTANCE.convertAccountBookEntityToGetAccountBookDetailVO(accountBook);
        } catch (Exception e) {
            log.error("查看账套明细异常 {}", e.getMessage(), e);
            throw new BizException("查看账套明细异常");
        }
    }

}
